Data Management
Read the two datasets from the repository on Github.
Extracted on year 2020 presidential election data.
Only included Democrats and Republican party votes.
Included variables: state_po, county_name, county_fips, party, candidatevotes.
Merged the above dataset election.final with FIPS to Geocode Dataset fips.code using the FIPS as the primary key.
election.data <- read.csv("https://raw.githubusercontent.com/VigneshReddy79/STA553-DataViz/main/Datasets/countypresidential_election_2000-2020.csv")
fips.code <- read.csv("https://raw.githubusercontent.com/VigneshReddy79/STA553-DataViz/main/Datasets/fips2geocode.csv")
election.2020 <- election.data %>%
filter( year == 2020 & (party == "DEMOCRAT" | party == "REPUBLICAN") ) %>%
mutate( votes.percent = round((candidatevotes/totalvotes)*100, 2) )
election.final <- election.2020 %>%
group_by( state_po, county_fips) %>%
summarise( highest.votespercent = max(votes.percent, na.rm = TRUE) )
`summarise()` has grouped output by 'state_po'. You can override using the `.groups` argument.
election.final <- merge( election.2020, election.final, by = "county_fips", all.x = FALSE)
election.final <- election.final %>%
filter( votes.percent == highest.votespercent )
election_fips <- merge(election.final, fips.code, by.x = "county_fips", by.y = "fips", all.x = FALSE)
election_fips <- election_fips %>%
mutate( republican = ifelse(party == "REPUBLICAN", yes = 1, no = 0)) %>%
mutate(state = state_po.x, party_won = party) %>%
select(state, county_fips, county_name, party_won, candidatevotes, totalvotes, votes.percent, republican, lat, lon)
election_fips$county_fips <- ifelse ((election_fips$county_fips < 10000),
yes = paste(0,election_fips$county_fips, sep = ""), no = election_fips$county_fips)
saveRDS(election_fips, file="D:/OneDrive - West Chester University of PA/Documents/Spring'22/STA553-DataViz/git/Datasets/election_fips.RData")
Choroleth map showing US Presidential Elections 2020 by county
Interactive Choropleth map using Plotly function
Created an interactive choropleth map to display the presidential election results at county level using two different colors to represent the two parties.
fig <- plot_ly() %>%
add_trace( type = "choropleth",
geojson = counties,
locations = election_fips$county_fips,
z = election_fips$republican,
colors = c("blue","red"),
zmin = 0,
zmax = 1,
text = ~paste("<br>County: ", election_fips$county_name,
"<br>Party won: ", election_fips$party,
"<br>Winner votes percent: ", election_fips$votes.percent,
"<br>Total votes: ", election_fips$totalvotes,
"<br>State: ", election_fips$state),
hoverinfo = "text",
marker = list(line=list(width=0.3))) %>%
hide_colorbar() %>%
layout( title = list(text = "<b>US Presidential elections 2020 by County</b>",
font = list(size = 20,
color = "darkred")),
margin = list( b = 15, l = 25, t = 85, r = 25),
legend = l,
geo = g)
fig
Error in normalizePath(path.expand(path), winslash, mustWork) :
path[1]="D:/OneDrive - West Chester University of PA/Documents/Spring'22/STA553-DataViz/git/.Rproj.user/shared/notebooks/7F43C2F2-Assignment-4/1/D1893DB9DF55DA44/cjg5dxg9hjfc3_t": The system cannot find the file specified
Interactive Choropleth map using Plotly function #2
This is another way to represent the US presidential election 2020 data by county. Created an interactive choropleth map to display the presidential election results at county level using the color palette to represent the votes percent for party.
fig2 <- plot_ly() %>%
add_trace( type = "choropleth",
geojson = counties,
locations = election_fips$county_fips,
z = election_fips$votes.percent,
colorscale = "TealGrn",
zmin = 0,
zmax = 100,
text = ~paste("<br>County: ", election_fips$county_name,
"<br>Party won: ", election_fips$party,
"<br>Winner votes percent: ", election_fips$votes.percent,
"<br>Total votes: ", election_fips$totalvotes,
"<br>State: ", election_fips$state),
hoverinfo = "text",
marker = list(line=list(width=0.3))) %>%
colorbar(title = "Winner Votes percent(%)") %>%
layout( title = list(text = "<b>US Presidential elections 2020 by County</b>",
font = list(size = 20,
color = "darkred")),
margin = list( b = 15, l = 25, t = 85, r = 25),
geo = g)
fig2
Choropleth map using Tableau Public
Using the Tableau, created the choropleth map as described in Part I of this assignment.
Created the map with Tableau and published it on Tableau’s public server.
Embeded the map into RMarkdown using the IMG tag from directly tableau public server link(hence embeded it to the knitted HTML file).
The link for the visualization created in Tableau public is: click here
LS0tDQp0aXRsZTogIkFzc2lnbm1lbnQtNCINCmF1dGhvcjogIlNhaSBWaWduZXNoIFJlZGR5IENob2xsZXRpIg0KZGF0ZTogIjA0LzAyLzIwMjIiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6IA0KICAgIHRvYzogeWVzDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgaHRtbF9ub3RlYm9vazoNCiAgICB0b2M6IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQplZGl0b3Jfb3B0aW9uczoNCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGlubGluZQ0KLS0tDQoNCjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+DQoNCmRpdiNUT0MgbGkgew0KICAgIGxpc3Qtc3R5bGU6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLWltYWdlOm5vbmU7DQogICAgYmFja2dyb3VuZC1yZXBlYXQ6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOjA7DQp9DQpoMS50aXRsZSB7DQogIGZvbnQtc2l6ZTogMjRweDsNCiAgY29sb3I6IERhcmtSZWQ7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCmg0LmF1dGhvciB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgY29sb3I6IERhcmtSZWQ7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCmg0LmRhdGUgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICBmb250LXNpemU6IDE4cHg7DQogIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICBjb2xvcjogRGFya0JsdWU7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCmgxIHsgLyogSGVhZGVyIDEgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDIycHg7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IGRhcmtyZWQ7DQogICAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KaDIgeyAvKiBIZWFkZXIgMiAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMThweDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoMyB7IC8qIEhlYWRlciAzIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxNXB4Ow0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBuYXZ5Ow0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCmg0IHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDE4cHg7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IGRhcmtyZWQ7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCjwvc3R5bGU+DQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KaWYgKCFyZXF1aXJlKCJ0aWR5dmVyc2UiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygidGlkeXZlcnNlIikNCiAgIGxpYnJhcnkodGlkeXZlcnNlKQ0KfQ0KaWYgKCFyZXF1aXJlKCJrbml0ciIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJrbml0ciIpDQogICBsaWJyYXJ5KGtuaXRyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJjb3dwbG90IikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImNvd3Bsb3QiKQ0KICAgbGlicmFyeShjb3dwbG90KQ0KfQ0KaWYgKCFyZXF1aXJlKCJsYXRleDJleHAiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygibGF0ZXgyZXhwIikNCiAgIGxpYnJhcnkobGF0ZXgyZXhwKQ0KfQ0KaWYgKCFyZXF1aXJlKCJwbG90bHkiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygicGxvdGx5IikNCiAgIGxpYnJhcnkocGxvdGx5KQ0KfQ0KaWYgKCFyZXF1aXJlKCJnYXBtaW5kZXIiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygiZ2FwbWluZGVyIikNCiAgIGxpYnJhcnkoZ2FwbWluZGVyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJwbmciKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoInBuZyIpICAgICAgICAgICAgICMgSW5zdGFsbCBwbmcgcGFja2FnZQ0KICAgIGxpYnJhcnkoInBuZyIpDQp9DQppZiAoIXJlcXVpcmUoIlJDdXJsIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJSQ3VybCIpICAgICAgICAgICAgICMgSW5zdGFsbCBSQ3VybCBwYWNrYWdlDQogICAgbGlicmFyeSgiUkN1cmwiKQ0KfQ0KaWYgKCFyZXF1aXJlKCJjb2xvdXJwaWNrZXIiKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoImNvbG91cnBpY2tlciIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJjb2xvdXJwaWNrZXIiKQ0KfQ0KaWYgKCFyZXF1aXJlKCJnZ2FuaW1hdGUiKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoImdnYW5pbWF0ZSIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJnZ2FuaW1hdGUiKQ0KfQ0KaWYgKCFyZXF1aXJlKCJnaWZza2kiKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoImdpZnNraSIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJnaWZza2kiKQ0KfQ0KaWYgKCFyZXF1aXJlKCJtYWdpY2siKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoIm1hZ2ljayIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJtYWdpY2siKQ0KfQ0KaWYgKCFyZXF1aXJlKCJnckRldmljZXMiKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoImdyRGV2aWNlcyIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJnckRldmljZXMiKQ0KfQ0KaWYgKCFyZXF1aXJlKCJqcGVnIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJqcGVnIikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoImpwZWciKQ0KfQ0KIyBrbml0cjo6b3B0c19rbml0JHNldChyb290LmRpciA9ICJDOi9Vc2Vycy83NUNQRU5HL09uZURyaXZlIC0gV2VzdCBDaGVzdGVyIFVuaXZlcnNpdHkgb2YgUEEvRG9jdW1lbnRzIikNCiMga25pdHI6Om9wdHNfa25pdCRzZXQocm9vdC5kaXIgPSAiQzpcXFNUQTQ5MFxcdzA1IikNCiMjDQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgIHdhcm5pbmcgPSBGQUxTRSwgICANCiAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBUUlVFLCAgIA0KICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBGQUxTRSkNCmBgYA0KDQojIERhdGEgTWFuYWdlbWVudA0KDQpSZWFkIHRoZSB0d28gZGF0YXNldHMgZnJvbSB0aGUgcmVwb3NpdG9yeSBvbiBHaXRodWIuDQo8bGk+RXh0cmFjdGVkIG9uIHllYXIgMjAyMCBwcmVzaWRlbnRpYWwgZWxlY3Rpb24gZGF0YS48L2xpPg0KPGxpPk9ubHkgaW5jbHVkZWQgRGVtb2NyYXRzIGFuZCBSZXB1YmxpY2FuIHBhcnR5IHZvdGVzLjwvbGk+DQo8bGk+SW5jbHVkZWQgdmFyaWFibGVzOiBzdGF0ZV9wbywgY291bnR5X25hbWUsIGNvdW50eV9maXBzLCBwYXJ0eSwgY2FuZGlkYXRldm90ZXMuPC9saT4NCjxsaT5NZXJnZWQgdGhlIGFib3ZlIGRhdGFzZXQgKmVsZWN0aW9uLmZpbmFsKiB3aXRoIEZJUFMgdG8gR2VvY29kZSBEYXRhc2V0ICpmaXBzLmNvZGUqIHVzaW5nIHRoZSBGSVBTIGFzIHRoZSBwcmltYXJ5IGtleS48L2xpPg0KPGJyPg0KYGBge3J9DQoNCmVsZWN0aW9uLmRhdGEgPC0gcmVhZC5jc3YoImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9WaWduZXNoUmVkZHk3OS9TVEE1NTMtRGF0YVZpei9tYWluL0RhdGFzZXRzL2NvdW50eXByZXNpZGVudGlhbF9lbGVjdGlvbl8yMDAwLTIwMjAuY3N2IikNCmZpcHMuY29kZSA8LSByZWFkLmNzdigiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL1ZpZ25lc2hSZWRkeTc5L1NUQTU1My1EYXRhVml6L21haW4vRGF0YXNldHMvZmlwczJnZW9jb2RlLmNzdiIpDQoNCmVsZWN0aW9uLjIwMjAgPC0gZWxlY3Rpb24uZGF0YSAlPiUNCiAgZmlsdGVyKCB5ZWFyID09IDIwMjAgJiAocGFydHkgPT0gIkRFTU9DUkFUIiB8IHBhcnR5ID09ICJSRVBVQkxJQ0FOIikgKSAlPiUNCiAgbXV0YXRlKCB2b3Rlcy5wZXJjZW50ID0gcm91bmQoKGNhbmRpZGF0ZXZvdGVzL3RvdGFsdm90ZXMpKjEwMCwgMikgKQ0KICANCmVsZWN0aW9uLmZpbmFsIDwtIGVsZWN0aW9uLjIwMjAgJT4lDQogIGdyb3VwX2J5KCBzdGF0ZV9wbywgY291bnR5X2ZpcHMpICU+JQ0KICBzdW1tYXJpc2UoIGhpZ2hlc3Qudm90ZXNwZXJjZW50ID0gbWF4KHZvdGVzLnBlcmNlbnQsIG5hLnJtID0gVFJVRSkgKQ0KDQplbGVjdGlvbi5maW5hbCA8LSBtZXJnZSggZWxlY3Rpb24uMjAyMCwgZWxlY3Rpb24uZmluYWwsIGJ5ID0gImNvdW50eV9maXBzIiwgYWxsLnggPSBGQUxTRSkNCg0KZWxlY3Rpb24uZmluYWwgPC0gZWxlY3Rpb24uZmluYWwgJT4lDQogIGZpbHRlciggdm90ZXMucGVyY2VudCA9PSBoaWdoZXN0LnZvdGVzcGVyY2VudCApDQoNCmVsZWN0aW9uX2ZpcHMgPC0gbWVyZ2UoZWxlY3Rpb24uZmluYWwsIGZpcHMuY29kZSwgYnkueCA9ICJjb3VudHlfZmlwcyIsIGJ5LnkgPSAiZmlwcyIsIGFsbC54ID0gICAgICAgICAgICAgICAgICAgICAgICBGQUxTRSkNCg0KZWxlY3Rpb25fZmlwcyA8LSBlbGVjdGlvbl9maXBzICU+JQ0KICBtdXRhdGUoIHJlcHVibGljYW4gPSBpZmVsc2UocGFydHkgPT0gIlJFUFVCTElDQU4iLCB5ZXMgPSAxLCBubyA9IDApKSAlPiUNCiAgbXV0YXRlKHN0YXRlID0gc3RhdGVfcG8ueCwgcGFydHlfd29uID0gcGFydHkpICU+JQ0KICBzZWxlY3Qoc3RhdGUsIGNvdW50eV9maXBzLCBjb3VudHlfbmFtZSwgcGFydHlfd29uLCBjYW5kaWRhdGV2b3RlcywgdG90YWx2b3Rlcywgdm90ZXMucGVyY2VudCwgICAgICAgICAgcmVwdWJsaWNhbiwgbGF0LCBsb24pDQoNCmVsZWN0aW9uX2ZpcHMkY291bnR5X2ZpcHMgPC0gIGlmZWxzZSAoKGVsZWN0aW9uX2ZpcHMkY291bnR5X2ZpcHMgPCAxMDAwMCksDQogIHllcyA9IHBhc3RlKDAsZWxlY3Rpb25fZmlwcyRjb3VudHlfZmlwcywgc2VwID0gIiIpLCBubyA9IGVsZWN0aW9uX2ZpcHMkY291bnR5X2ZpcHMpDQoNCnNhdmVSRFMoZWxlY3Rpb25fZmlwcywgZmlsZT0iRDovT25lRHJpdmUgLSBXZXN0IENoZXN0ZXIgVW5pdmVyc2l0eSBvZiBQQS9Eb2N1bWVudHMvU3ByaW5nJzIyL1NUQTU1My1EYXRhVml6L2dpdC9EYXRhc2V0cy9lbGVjdGlvbl9maXBzLlJEYXRhIikNCg0KYGBgDQoNCiMgQ2hvcm9sZXRoIG1hcCBzaG93aW5nIFVTIFByZXNpZGVudGlhbCBFbGVjdGlvbnMgMjAyMCBieSBjb3VudHkNCg0KIyMgSW50ZXJhY3RpdmUgQ2hvcm9wbGV0aCBtYXAgdXNpbmcgUGxvdGx5IGZ1bmN0aW9uDQoNCjxsaT5DcmVhdGVkIGFuIGludGVyYWN0aXZlIGNob3JvcGxldGggbWFwIHRvIGRpc3BsYXkgdGhlIHByZXNpZGVudGlhbCBlbGVjdGlvbiByZXN1bHRzIGF0IGNvdW50eSBsZXZlbCB1c2luZyB0d28gZGlmZmVyZW50IGNvbG9ycyB0byByZXByZXNlbnQgdGhlIHR3byBwYXJ0aWVzLjwvbGk+DQo8YnI+DQpgYGB7cn0NCg0KdXJsIDwtICJodHRwczovL2dpdGh1Yi5jb20vcGVuZ2RzY2kvc3RhNTUzL3Jhdy9tYWluL2RhdGEvZ2VvanNvbi1jb3VudGllcy1maXBzLmpzb24iDQpjb3VudGllcyA8LSByanNvbjo6ZnJvbUpTT04oZmlsZT11cmwpDQoNCmcgPC0gbGlzdChzY29wZSA9ICd1c2EnLA0KICAgICAgICAgIHByb2plY3Rpb24gPSBsaXN0KHR5cGUgPSAnYWxiZXJzIHVzYScpLA0KICAgICAgICAgIHNob3dsYWtlcyA9IFRSVUUsDQogICAgICAgICAgbGFrZWNvbG9yID0gdG9SR0IoJ3doaXRlJykpDQoNCmZpZyA8LSBwbG90X2x5KCkgICU+JSANCiAgYWRkX3RyYWNlKCB0eXBlID0gImNob3JvcGxldGgiLA0KICAgICAgICAgIGdlb2pzb24gPSBjb3VudGllcywNCiAgICAgICAgbG9jYXRpb25zID0gZWxlY3Rpb25fZmlwcyRjb3VudHlfZmlwcywNCiAgICAgICAgICAgICAgICB6ID0gZWxlY3Rpb25fZmlwcyRyZXB1YmxpY2FuLA0KICAgICAgICAgICBjb2xvcnMgPSBjKCJibHVlIiwicmVkIiksDQogICAgICAgICAgICAgem1pbiA9IDAsDQogICAgICAgICAgICAgem1heCA9IDEsDQogICAgICAgICAgICAgdGV4dCA9IH5wYXN0ZSgiPGJyPkNvdW50eTogIiwgZWxlY3Rpb25fZmlwcyRjb3VudHlfbmFtZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICI8YnI+UGFydHkgd29uOiAiLCBlbGVjdGlvbl9maXBzJHBhcnR5LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIjxicj5XaW5uZXIgdm90ZXMgcGVyY2VudDogIiwgZWxlY3Rpb25fZmlwcyR2b3Rlcy5wZXJjZW50LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIjxicj5Ub3RhbCB2b3RlczogIiwgZWxlY3Rpb25fZmlwcyR0b3RhbHZvdGVzLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIjxicj5TdGF0ZTogIiwgZWxlY3Rpb25fZmlwcyRzdGF0ZSksDQogICAgICAgIGhvdmVyaW5mbyA9ICJ0ZXh0IiwNCiAgICAgICAgICAgbWFya2VyID0gbGlzdChsaW5lPWxpc3Qod2lkdGg9MC4zKSkpICAgJT4lIA0KICBoaWRlX2NvbG9yYmFyKCkgJT4lDQogIGxheW91dCggdGl0bGUgPSBsaXN0KHRleHQgPSAiPGI+VVMgUHJlc2lkZW50aWFsIGVsZWN0aW9ucyAyMDIwIGJ5IENvdW50eTwvYj4iLA0KICAgICAgICAgICAgICAgICAgICAgICBmb250ID0gbGlzdChzaXplID0gMjAsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gImRhcmtyZWQiKSksDQogICAgICAgICAgbWFyZ2luID0gbGlzdCggYiA9IDE1LCBsID0gMjUsIHQgPSA4NSwgciA9IDI1KSwNCiAgICAgICAgICBnZW8gPSBnKQ0KZmlnDQpgYGANCg0KIyMgSW50ZXJhY3RpdmUgQ2hvcm9wbGV0aCBtYXAgdXNpbmcgUGxvdGx5IGZ1bmN0aW9uICMyDQoNCjxsaT4gVGhpcyBpcyBhbm90aGVyIHdheSB0byByZXByZXNlbnQgdGhlIFVTIHByZXNpZGVudGlhbCBlbGVjdGlvbiAyMDIwIGRhdGEgYnkgY291bnR5LiBDcmVhdGVkIGFuIGludGVyYWN0aXZlIGNob3JvcGxldGggbWFwIHRvIGRpc3BsYXkgdGhlIHByZXNpZGVudGlhbCBlbGVjdGlvbiByZXN1bHRzIGF0IGNvdW50eSBsZXZlbCB1c2luZyB0aGUgY29sb3IgcGFsZXR0ZSB0byByZXByZXNlbnQgdGhlIHZvdGVzIHBlcmNlbnQgZm9yIHBhcnR5LjwvbGk+DQo8YnI+DQpgYGB7cn0NCmxpYnJhcnkoIlJDb2xvckJyZXdlciIpDQpmaWcyIDwtIHBsb3RfbHkoKSAgJT4lIA0KICBhZGRfdHJhY2UoIHR5cGUgPSAiY2hvcm9wbGV0aCIsDQogICAgICAgICAgZ2VvanNvbiA9IGNvdW50aWVzLA0KICAgICAgICBsb2NhdGlvbnMgPSBlbGVjdGlvbl9maXBzJGNvdW50eV9maXBzLA0KICAgICAgICAgICAgICAgIHogPSBlbGVjdGlvbl9maXBzJHZvdGVzLnBlcmNlbnQsDQogICAgICAgY29sb3JzY2FsZSA9ICJUZWFsR3JuIiwgIA0KICAgICAgICAgICAgIHptaW4gPSAwLA0KICAgICAgICAgICAgIHptYXggPSAxMDAsDQogICAgICAgICAgICAgdGV4dCA9IH5wYXN0ZSgiPGJyPkNvdW50eTogIiwgZWxlY3Rpb25fZmlwcyRjb3VudHlfbmFtZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICI8YnI+UGFydHkgd29uOiAiLCBlbGVjdGlvbl9maXBzJHBhcnR5LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIjxicj5XaW5uZXIgdm90ZXMgcGVyY2VudDogIiwgZWxlY3Rpb25fZmlwcyR2b3Rlcy5wZXJjZW50LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIjxicj5Ub3RhbCB2b3RlczogIiwgZWxlY3Rpb25fZmlwcyR0b3RhbHZvdGVzLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIjxicj5TdGF0ZTogIiwgZWxlY3Rpb25fZmlwcyRzdGF0ZSksDQogICAgICAgIGhvdmVyaW5mbyA9ICJ0ZXh0IiwNCiAgICAgICAgICAgbWFya2VyID0gbGlzdChsaW5lPWxpc3Qod2lkdGg9MC4zKSkpICU+JSANCiAgY29sb3JiYXIodGl0bGUgPSAiV2lubmVyIFZvdGVzIHBlcmNlbnQoJSkiKSAlPiUgDQogIGxheW91dCggdGl0bGUgPSBsaXN0KHRleHQgPSAiPGI+VVMgUHJlc2lkZW50aWFsIGVsZWN0aW9ucyAyMDIwIGJ5IENvdW50eTwvYj4iLA0KICAgICAgICAgICAgICAgICAgICAgICBmb250ID0gbGlzdChzaXplID0gMjAsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gImRhcmtyZWQiKSksDQogICAgICAgICAgbWFyZ2luID0gbGlzdCggYiA9IDE1LCBsID0gMjUsIHQgPSA4NSwgciA9IDI1KSwNCiAgICAgICAgICBnZW8gPSBnKQ0KZmlnMg0KYGBgDQoNCiMjIENob3JvcGxldGggbWFwIHVzaW5nIFRhYmxlYXUgUHVibGljDQoNClVzaW5nIHRoZSBUYWJsZWF1LCBjcmVhdGVkIHRoZSBjaG9yb3BsZXRoIG1hcCBhcyBkZXNjcmliZWQgaW4gUGFydCBJIG9mIHRoaXMgYXNzaWdubWVudC4NCjxsaT5DcmVhdGVkIHRoZSBtYXAgd2l0aCBUYWJsZWF1IGFuZCBwdWJsaXNoZWQgaXQgb24gVGFibGVhdSdzIHB1YmxpYyBzZXJ2ZXIuPC9saT4NCjxsaT5FbWJlZGVkIHRoZSBtYXAgaW50byBSTWFya2Rvd24gdXNpbmcgdGhlIElNRyB0YWcgZnJvbSBkaXJlY3RseSB0YWJsZWF1IHB1YmxpYyBzZXJ2ZXIgbGluayhoZW5jZSBlbWJlZGVkIGl0IHRvIHRoZSBrbml0dGVkIEhUTUwgZmlsZSkuPC9saT4NCjxsaT4gVGhlIGxpbmsgZm9yIHRoZSB2aXN1YWxpemF0aW9uIGNyZWF0ZWQgaW4gVGFibGVhdSBwdWJsaWMgaXM6IDxhIGhyZWY9Imh0dHBzOi8vcHVibGljLnRhYmxlYXUuY29tL3ZpZXdzL1VTcHJlc2lkZW50aWFsZWxlY3Rpb25zMjAyMC9TaGVldDE/Omxhbmd1YWdlPWVuLVVTJjpkaXNwbGF5X2NvdW50PW4mOm9yaWdpbj12aXpfc2hhcmVfbGluayIgdGFyZ2V0PSJfYmxhbmsiPmNsaWNrIGhlcmU8L2E+IDwvbGk+DQo8YnI+DQo8aW1nIHNyYz0gImh0dHBzOi8vcHVibGljLnRhYmxlYXUuY29tL3N0YXRpYy9pbWFnZXMvVVMvVVNwcmVzaWRlbnRpYWxlbGVjdGlvbnMyMDIwL1NoZWV0MS8xLnBuZyI+IDwvaW1nPg0KPGJyPg0KPGJyPg0K